/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package chat.room;

import java.util.Collection;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Random;

/**
 *
 * @author salm
 */
public class ChatRoom
{
    private String roomID;
    private HashSet<String> users = new HashSet();
    private HashSet<String> listenUsers = new HashSet();
    private String talkUser;
    private Collection<IChatRoomEventListener> eventListeners = new LinkedList();
    private String roomName;
    
    public ChatRoom(String roomID, String roomName)
    {
        this.roomID = roomID;
        this.roomName = roomName;
    }

    /**
     * @return the roomID
     */
    public String getRoomID() {
        return roomID;
    }

    /**
     * @return the users
     */
    public Iterable<String> getUsers() {
        return users;
    }

    /**
     * @return the eventListeners
     */
    public Collection<IChatRoomEventListener> getEventListeners() {
        return eventListeners;
    }
    
    public boolean addUser(String userID)
    {
        if (this.users.add(userID))
        {
            for (IChatRoomEventListener listener : this.eventListeners)
            {
                listener.userJoined(this, userID);
            }
            
            return true;
        }
        
        return false;
    }
    
    public boolean removeUser(String userID)
    {
        this.removeListenUser(userID);
        if (this.users.remove(userID))
        {
            for (IChatRoomEventListener listener : this.eventListeners)
            {
                listener.userLeft(this, userID);
            }
            
            return true;
        }
        
        return false;
    }
    
    public boolean addListenUser(String userID)
    {
        if (this.users.contains(userID))
        {
            boolean result = this.listenUsers.add(userID);
            
            if (this.talkUser == null)
            {
                this.setTalkUser(null);
            }
            
            return result;
        }
        
        return false;
    }
    
    public boolean removeListenUser(String userID)
    {
        if (this.users.contains(userID))
        {
            boolean result = this.listenUsers.remove(userID);
            
            if (this.talkUser == null ? userID == null : this.talkUser.equals(userID))
            {
                this.setTalkUser(null);
            }
            
            return result;
        }
        
        return false;
    }

    /**
     * @return the listenUsers
     */
    public Iterable<String> getListenUsers() {
        return listenUsers;
    }

    /**
     * @return the talkUser
     */
    public String getTalkUser() {
        return talkUser;
    }

    /**
     * @param talkUser the talkUser to set
     */
    public void setTalkUser(String talkUser) {
        this.talkUser = talkUser;
        
        if (this.talkUser == null)
        {
            this.talkUser = this.chooseRandomTalker();
            
            for (IChatRoomEventListener listener : this.eventListeners)
            {
                listener.talkUserChanged(this, this.talkUser);
            }
        }
    }
    
    private String chooseRandomTalker()
    {
        Random r = new Random();
        int randomUserIndex = r.nextInt(this.listenUsers.size());
        for (String userID : this.listenUsers)
        {
            --randomUserIndex;
            if (randomUserIndex < 0)
            {
                return userID;
            }
        }
        
        return null;
    }
    
    @Override
    public String toString()
    {
        return String.format("%d: %s", this.roomID, this.roomName);
    }

    /**
     * @return the roomName
     */
    public String getRoomName() {
        return roomName;
    }

    /**
     * @param roomName the roomName to set
     */
    public void setRoomName(String roomName) {
        this.roomName = roomName;
    }
}
